package com.yykj.drup.server.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yykj.common.service.RedisService;
import com.yykj.common.vo.ResultVO;
import com.yykj.drup.client.WiFenXiaoOrder;
import com.yykj.drup.server.constant.SysConstant;
import com.yykj.drup.server.dto.OrderDetailsDto;
import com.yykj.drup.server.dto.PrescriptionProductDto;
import com.yykj.drup.server.dto.PrescriptionStoreProductDto;
import com.yykj.drup.server.form.OrderForm;
import com.yykj.drup.server.form.PaymentParamFrom;
import com.yykj.drup.server.form.PrescriptionForm;
import com.yykj.drup.server.form.WestDrug;
import com.yykj.drup.server.model.Order;
import com.yykj.drup.server.model.OrderInfo;
import com.yykj.drup.server.param.OrderInfoParam;
import com.yykj.drup.server.param.OrderProductParam;
import com.yykj.drup.server.service.*;
import com.yykj.drup.server.service.feign.MessageCenterServerFeign;
import com.yykj.drup.server.service.feign.PayCenterServerFeign;
import com.yykj.drup.server.service.feign.PrescriptionServerFeign;
import com.yykj.drup.server.service.feign.WiFenXiaoServerFeign;
import com.yykj.message.center.client.dto.DrugOrderMessageBodyDTO;
import com.yykj.message.center.client.dto.pay.DrugOrderCancelMessageBodyDTO;
import com.yykj.pay.center.client.form.PayCreateForm;
import com.yykj.prescription.client.dto.PrescriptionDetailDTO;
import com.yykj.prescription.client.dto.PrescriptionOrderCheckResultDTO;
import io.swagger.annotations.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * @Author zeng
 * @Date 2022/3/17
 */
@RestController
@Api(tags = "药品订单管理")
@RequestMapping("/api/drug")
@AllArgsConstructor
@Slf4j
public class ProductPayOrderController {

    final OrderService orderService;
    final OrderInfoService orderInfoService;
    final DoctorStoreService doctorStoreService;
    final ProductPayOrderService productPayOrderService;
    final OrderDetailsService orderDetailsService;
    final PayCenterServerFeign payFeignClient;
    final MessageCenterServerFeign messageCenterServerFeign;
    final PrescriptionServerFeign prescriptionServerFeign;
    final WiFenXiaoServerFeign wiFenXiaoServerFeign;
    final ExpressService expressService;
    final ProductService productService;
    @Autowired
    RedisService redisService;

    @ApiOperation("根据处方id，获取推荐药店-药品信息（患者端）")
    @GetMapping("/productPayOrder/findStoreProducts")
    @ApiImplicitParam(name = "prescriptionId",value = "处方主键ID")
    @ApiResponses({
            @ApiResponse(code = 0,message = "",response = PrescriptionStoreProductDto.class)
    })
    public ResultVO findStoreProducts(@RequestParam(value = "prescriptionId") String prescriptionId){
        //feign调取prescription-server，根据处方标识获取处方中药品集合 X00120220317000003
        ResultVO<PrescriptionDetailDTO> prescriptionDetailDTOResultVO = prescriptionServerFeign.prescriptionInfo(prescriptionId);
        if (prescriptionDetailDTOResultVO.getCode() != 0){
            return prescriptionDetailDTOResultVO;
        }
        PrescriptionForm prescriptionForm = new PrescriptionForm();
        PrescriptionDetailDTO detailDTO = prescriptionDetailDTOResultVO.getData();
        //获取医生主键ID
        prescriptionForm.setDoctorId(detailDTO.getDoctorId());
        //获取整理药方药品数据
        List<WestDrug> westDrugs = productService.findWestDrugs(detailDTO);
        //List<WestDrug> westDrugs = BeanUtil.copyToList(detailDTO.getWestDrugList(), WestDrug.class);
        prescriptionForm.setWestDrugs(westDrugs);
        //获取处方医生常用药店排序后的标识集合
        List<Integer> storIds = doctorStoreService.findStoreIdsSortByDoctocId(prescriptionForm.getDoctorId());
        //获取处方药品以及药店信息
        List<PrescriptionStoreProductDto> productDtos = productPayOrderService.findStoreProductInfoByProductIds(storIds, westDrugs);
        productDtos.stream().forEach(i->{
            List<PrescriptionProductDto> products = i.getProducts();
            i.setProductNumber(products.size());
            BigDecimal totalPrice = products.stream().map(PrescriptionProductDto::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            i.setTotalPrice(totalPrice);
        });
        return ResultVO.success(productDtos);
    }

    @ApiOperation("添加订单（患者端）")
    @PostMapping("/productPayOrder/insertOrder")
    public ResultVO insertOrder(@RequestBody @Validated OrderForm orderForm){
        ResultVO<PrescriptionOrderCheckResultDTO> resultVO = prescriptionServerFeign.checkPrescriptionOrder(orderForm.getPrescriptionId());
        if (!resultVO.getData().getAvailable()){
            return ResultVO.error(resultVO.getData().getMessage());
        }
        //插入系统总订单，返回订单号
        String orderNumber = orderService.insertSysOrder(orderForm);
        if (StrUtil.isNotBlank(orderNumber)){
            //插入药店订单
            orderInfoService.insertOrderByOrderForm(orderNumber,orderForm);
            //发送message消息
            DrugOrderMessageBodyDTO messageBodyDTO = new DrugOrderMessageBodyDTO();
            messageBodyDTO.setHospitalId(orderForm.getHospitalId());
            messageBodyDTO.setPrescriptionId(orderForm.getPrescriptionId());
            messageCenterServerFeign.sendDrugOrderMessage(messageBodyDTO);
            //发送订单延迟取消message消息
            DrugOrderCancelMessageBodyDTO cancelMessageBodyDTO = new DrugOrderCancelMessageBodyDTO();
            cancelMessageBodyDTO.setOrderNum(orderNumber);
            cancelMessageBodyDTO.setCancelTime(orderService.getCancelTime());
            messageCenterServerFeign.sendCancelDrugOrderMessage(cancelMessageBodyDTO);
            return ResultVO.success(orderNumber);
        }
        return ResultVO.error("下单失败");
    }

    @ApiOperation("获取订单列表（后台）")
    @PostMapping("/productPayOrder/orderListPage")
    public ResultVO<IPage<Order>> orderListPage(@RequestBody OrderInfoParam param){
        IPage<Order> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper
                .eq(Order::getIsDeleted,0)
                .eq(param.getOrderStatus() != null,Order::getOrderStatus,param.getOrderStatus())
                .eq(StrUtil.isNotEmpty(param.getOrderNum()), Order::getOrderSysNumber,param.getOrderNum())
                .like(StrUtil.isNotEmpty(param.getOrderUserName()),Order::getConsultUserName,param.getOrderUserName())
                .like(StrUtil.isNotEmpty(param.getOrderUserAddress()),Order::getConsultUserAddress,param.getOrderUserAddress())
                .like(StrUtil.isNotEmpty(param.getOrderUserPhone()),Order::getConsultUserPhone,param.getOrderUserPhone())
                .orderByDesc(Order::getCreatedTime);
        if(!StrUtil.isBlankIfStr(param.getStartDate()) && !StrUtil.isBlankIfStr(param.getEndDate())){
            wrapper.between(!StrUtil.isBlankIfStr(param.getStartDate()),Order::getCreatedTime,param.getStartDate(),param.getEndDate().plusDays(1));
        }
        return ResultVO.success(orderService.getOrderInfosPage(page, wrapper));
    }

    @ApiOperation("获取订单信息列表（患者端）")
    @PostMapping("/productPayOrder/productListByOrderId")
    public ResultVO<IPage<Order>> productListByOrderId(@RequestBody @Validated OrderProductParam param){
        IPage<Order> orderInfosPage = orderService.findOrderInfosPage(param);
        //获取药店订单在微分销的物流信息
        orderInfosPage.getRecords().stream().forEach(order -> {
            List<OrderInfo> orderInfo = order.getStoreOrders();
            orderInfo.stream().forEach(storeOrder -> {
                if (StrUtil.isEmpty(storeOrder.getOrderComNumber()) && order.getOrderStatus() == 2 && StrUtil.isNotEmpty(storeOrder.getOrgOrderNum())){
                    log.info("查询药店订单在第三方的物流信息,第三方订单号{}",storeOrder.getOrgOrderNum());
                    //查询药店订单在第三方的物流信息
                    WiFenXiaoOrder wiFenXiaoOrder = wiFenXiaoServerFeign.findOrder(storeOrder.getOrgOrderNum());
                    if (BeanUtil.isNotEmpty(wiFenXiaoOrder) && wiFenXiaoOrder.getExpress_no() != null && wiFenXiaoOrder.getExpress_name() != null){
                        //更新药店订单物流信息
                        orderInfoService.setOrderInfoComNumber(wiFenXiaoOrder.getOrder_no(),wiFenXiaoOrder.getExpress_name(),wiFenXiaoOrder.getExpress_no());
                        //订阅物流
                        expressService.expressPoll(wiFenXiaoOrder.getExpress_no(),null,null);
                        //插入物流信息
                        expressService.insertExpressContextQueryTrackData(wiFenXiaoOrder.getExpress_no());
                        storeOrder.setOrderComNumber(wiFenXiaoOrder.getExpress_no());
                        storeOrder.setOrderCom(wiFenXiaoOrder.getExpress_name());
                    }
                }
            });
        });
        return ResultVO.success(orderService.findOrderInfosPage(param));
    }

    @ApiOperation("获取订单详情（患者端）")
    @ApiImplicitParam(name = "orderSysId",value = "系统订单主键ID",required = true)
    @GetMapping("/productPayOrder/productByOrderId")
    public ResultVO<OrderDetailsDto> productByOrderId(@RequestParam("orderSysId") Integer orderSysId){
        return ResultVO.success(orderService.findOrderDeteilsById(orderSysId));
    }

    @ApiOperation("获取小程序微信支付调起支付页面必要参数（患者端）")
    @PostMapping("/productPayOrder/getPaymentParam")
    public ResultVO getPaymentParam(@RequestBody @Valid PaymentParamFrom from){
       //获取订单信息
       Order order = orderService.getByOrderNum(from.getOrderNo());
        if (order == null){
            return ResultVO.error("订单不存在");
        }
        BigDecimal decimal = order.getOrderTotalPrice().multiply(new BigDecimal(100));// 单位分
        PayCreateForm payCreateForm = new PayCreateForm();
        payCreateForm.setAmount(decimal.intValue());
        payCreateForm.setOpenId(from.getOpenId());
        payCreateForm.setOrderNo(from.getOrderNo());
        payCreateForm.setAttach("drup-productPay");
        payCreateForm.setDescription("药品下单");
        payCreateForm.setHospitalId(order.getHospitalId());
        ResultVO<Map<String, String>> mapResultVO = payFeignClient.create(payCreateForm);
        mapResultVO.getData().put("orderSysId",order.getOrderSysId().toString());
        System.out.println(mapResultVO);
        return ResultVO.success(mapResultVO);
    }



    @ApiOperation("配置订单支付超时时间（后台）")
    @GetMapping("/productPayOrder/setOrderTimeoutValue")
    public ResultVO setOrderTimeoutValue(@RequestParam("value") String value){
        try {
            redisService.set("orderPayTimeout",value);
            return ResultVO.success();
        }catch (RuntimeException e){
            e.printStackTrace();
            return ResultVO.error(e.getMessage());
        }
    }

    @ApiOperation("获取订单支付超时时间（患者端）")
    @GetMapping("/productPayOrder/getOrderTimeoutValue")
    public ResultVO getOrderTimeoutValue(){
        try {
            String timeoutDef = SysConstant.timeoutDef;
            String timeout = redisService.get("orderPayTimeout");
            if (!StrUtil.isEmpty(timeout)){
                timeoutDef = timeout;
            }
            return ResultVO.success(timeoutDef);
        }catch (RuntimeException e){
            e.printStackTrace();
            return ResultVO.error(e.getMessage());
        }
    }
}
